package com.victualler.core.config.img.controller.impl;

import com.victualler.core.base.controller.impl.BaseRestControllerImpl;
import com.victualler.core.common.enums.ChecKDataErrorEnum;
import com.victualler.core.common.utils.ExceptionWapperUtil;
import com.victualler.core.config.img.controller.ImageItemController;
import com.victualler.core.config.img.dto.ItemBlock;
import com.victualler.core.config.img.entity.ImageDirDao;
import com.victualler.core.config.img.entity.ImageItemDao;
import com.victualler.core.config.img.enums.ImageTypeEnums;
import com.victualler.core.config.img.repository.ImageItemQueryRepository;
import com.victualler.core.config.img.repository.ImageItemRepository;
import com.victualler.core.config.img.service.ImageDirService;
import com.victualler.core.config.img.service.ImageItemService;
import net.coobird.thumbnailator.Thumbnails;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.core.io.Resource;
import org.springframework.core.io.ResourceLoader;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.multipart.MultipartFile;

import java.io.File;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.util.ArrayList;
import java.util.List;

/**
 * @Author: Guoshichang
 * @Date: Create in 11:57 2018/4/6
 * @Discription:
 */
@RestController
@RequestMapping("/config/img")
public class ImageItemControllerImpl extends BaseRestControllerImpl<ImageItemDao,ImageItemRepository,ImageItemQueryRepository,ImageItemService> implements ImageItemController {
    @Value("${upload.img}")
    private String preFilePath; //配置的统一文件存放路径
    @Autowired
    private   ResourceLoader resourceLoader;
    @Autowired
    private ImageDirService imageDirService; //文件夹服务类

    /**
     *  加载图片资源 以文件流的形式返回图片资源
     * @param id 图片id
     * @return
     */
    @RequestMapping(value = "loadImg/{id}",method = RequestMethod.GET)
    public Resource  getFile(@PathVariable Long id) {
        ImageItemDao imageItemDao = this.baseService.getById(id);
        //找到对应的资源并加载返回数据流
        String filePath = Paths.get(imageItemDao.getPrePath()+imageItemDao.getFilePath(), imageItemDao.getFileName()).toString();
        return resourceLoader.getResource("file:" + filePath );
    }

    /**
     *  加载图片资源 以文件流的形式返回图片资源
     * @param id 图片id
     * @return
     */
    @RequestMapping(value = "loadImg/{type}/{id}",method = RequestMethod.GET)
    public Resource  getFile(@PathVariable("type")String type,@PathVariable("id") Long id) {
        ImageItemDao imageItemDao = this.baseService.getById(id);
        //找到对应的资源并加载返回数据流
        String filePath = Paths.get(imageItemDao.getPrePath()+imageItemDao.getFilePath(),type+imageItemDao.getFileName()).toString();
        File file  = new File(filePath);
        //指定类型图片不存在
        if (!file.exists()) {
            try {
                //原图
                File oldFile = Paths.get(imageItemDao.getPrePath()+imageItemDao.getFilePath(),imageItemDao.getFileName()).toFile();
                if (ImageTypeEnums.NORMAL.getKey().equals(type)) {
                    System.out.println("重新生成[NORMAL]图片:"+filePath);
                    Thumbnails.of(oldFile).scale(0.7).outputQuality(0.7).toFile(filePath);
                } else if (ImageTypeEnums.SMALL.getKey().equals(type)) {
                    System.out.println("重新生成[SMALL]图片:"+filePath);
                    Thumbnails.of(oldFile).scale(0.5).outputQuality(0.5).toFile(filePath);
                } else {
                    throw ChecKDataErrorEnum.createException(ChecKDataErrorEnum.DATA_ERROR,"图片尺寸类型["+type+"]不正确!");
                }
            } catch (IOException e) {
                e.printStackTrace();
                throw ExceptionWapperUtil.wapper(e);
            }
        }
        return resourceLoader.getResource("file:" + filePath );
    }


    /**
     * /文件上传保存对应实体
     * @param file  上传文件
     * @param imageDirId  上传文件对应文件夹id
     * @return
     */
    @RequestMapping(value="saveAndUpload",method = RequestMethod.POST)
    public ImageItemDao saveAndUpload(@RequestParam("file") MultipartFile file,@RequestParam("imageDirId")  Long imageDirId) throws IOException {
        //上传并保存
        long fileSize=0;
        ImageDirDao dirItem = imageDirService.getById(imageDirId);
        String  realPath = preFilePath+dirItem.getDirPath();
        String  fileName = file.getOriginalFilename();
        //获取文件夹路径
        File dir = new File(realPath);
        if(!dir.exists()){
            dir.mkdirs();
        }
        //上传文件
        try {
            fileSize= Files.copy(file.getInputStream(),Paths.get(realPath,fileName));
            //生成普通尺寸的图片
            String normalPath = Paths.get(realPath, ImageTypeEnums.NORMAL.getKey()+fileName).toString();
            System.out.println("生成[NORMAL]图片:"+normalPath);
            Thumbnails.of(file.getInputStream()).scale(0.7).outputQuality(0.7).toFile(normalPath);
            //生成小尺寸的
            String smallPath = Paths.get(realPath,ImageTypeEnums.SMALL.getKey()+fileName).toString();
            System.out.println("生成[SMALL]图片:"+smallPath);
            Thumbnails.of(file.getInputStream()).scale(0.5).outputQuality(0.5).toFile(smallPath);
        } catch (IOException e) {
            throw  e;
        }
        //封装bean对象
        ImageItemDao  imageItemDao = new ImageItemDao(fileName,preFilePath,dirItem.getDirPath(),fileSize,dirItem.getId());
        System.err.println(imageItemDao);
        //保存图片实体
        this.baseService.save(imageItemDao);
        return imageItemDao;
    }

    /**
     * 保存文件夹
     * @param imageDirDao
     * @return
     */
    @RequestMapping("saveDir")
    @Override
    public void saveDir(@RequestBody ImageDirDao imageDirDao) throws Exception {

            ImageDirDao parentDir = imageDirService.getById(imageDirDao.getParentId());
            imageDirDao.setDirPath(parentDir.getDirPath() + imageDirDao.getName() +"/");
            String realPath = preFilePath + imageDirDao.getDirPath();
            //创建文件夹路径
            File file = new File(realPath);
            //如果已经存在
            if(!file.exists()){
                file.mkdirs();
                //保存
                imageDirService.save(imageDirDao);

            }else{
                throw new Exception("存在同名文件夹");
            }
    }

    @RequestMapping("delete/{id}")
    @Override
    public void deleteAndFile(@PathVariable  Long id) {
        ImageItemDao dao=this.baseService.getById(id);
        String fileName = dao.getPrePath() + dao.getFilePath() + dao.getFileName();
        System.out.println(fileName);
        //删除文件
        new File(fileName).delete();
        //删除其他尺寸
        String smallfileName = dao.getPrePath() + dao.getFilePath() + ImageTypeEnums.SMALL.getKey() + dao.getFileName();
        String normalfileName = dao.getPrePath() + dao.getFilePath() + ImageTypeEnums.NORMAL.getKey() + dao.getFileName();
        try {
            new File(smallfileName).delete();
            new File(normalfileName).delete();
        } catch (Exception e) {
            e.printStackTrace();
        }
        //删除实体
        this.baseService.deleteById(id);
    }

    @RequestMapping("deleteDir/{dirId}")
    @Override
    public void deleteDirAndFile(@PathVariable Long dirId) throws Exception {
        if(!this.imageDirService.dirIsUsed(dirId)){
            ImageDirDao imageDirDao = imageDirService.getById(dirId);
            //删除文件夹
            new File(this.preFilePath + imageDirDao.getDirPath()).delete();
            //删除实体
            this.imageDirService.deleteById(dirId);
        }else{
            throw new Exception("该文件夹已经被使用");
        }
    }

    /**
     * 根据父id 获取某个文件夹下的子文件夹列表
     * @param parentId
     * @return
     */
    @RequestMapping("getImageDirs/{parentId}")
    @Override
    public List<ItemBlock> getImageDirByParentId(@PathVariable  Long parentId){
        List<ItemBlock> items = new ArrayList<>();
        //加入文件夹列表
        List<ImageDirDao> resDirList = this.imageDirService.getByParentId(parentId);
        for (ImageDirDao imageDirDao:resDirList) {
            items.add(new ItemBlock(String.valueOf(imageDirDao.getId()),ItemBlock.TYPE_DIR,imageDirDao.getName()));
        }
        //加入图片列表
        List<ImageItemDao> resImgList = this.baseService.findByImageDirId(parentId);
        for (ImageItemDao imageItemDao:resImgList) {
            items.add(new ItemBlock(String.valueOf(imageItemDao.getId()),ItemBlock.TYPE_IMG,imageItemDao.getFileName()));
        }
        return items;
    }


}
